home *** CD-ROM | disk | FTP | other *** search
/ Amiga Magazin: Amiga-CD 1996 September & October / Amiga-CD 1996 #9-10.iso / ausgabe_9_96 / grafik / amipeg05 / parseblock.c < prev    next >
C/C++ Source or Header  |  1994-04-22  |  5KB  |  207 lines

  1. /*
  2.  *  This source handles parsing and supervises decoding of the blocks and
  3.  *  passes the decoded data to the idct.
  4.  */
  5.  
  6.  
  7. #define NO_SANITY_CHECKS
  8. #include "video.h"
  9. #include "proto.h"
  10. #include "decoders.h"
  11.  
  12. #define static
  13.  
  14. /* External declarations. */
  15.  
  16. extern int zigzag_direct[];
  17.  
  18.  
  19. /*
  20.  *--------------------------------------------------------------
  21.  *
  22.  * ParseReconBlock --
  23.  *
  24.  *    Parse values for block structure from bitstream.
  25.  *      n is an indication of the position of the block within
  26.  *      the macroblock (i.e. 0-5) and indicates the type of 
  27.  *      block (i.e. luminance or chrominance). Reconstructs
  28.  *      coefficients from values parsed and puts in 
  29.  *      block.dct_recon array in vid stream structure.
  30.  *      sparseFlag is set when the block contains only one
  31.  *      coeffictient and is used by the IDCT.
  32.  *
  33.  * Results:
  34.  *    
  35.  *
  36.  * Side effects:
  37.  *      Bit stream irreversibly parsed.
  38.  *
  39.  *--------------------------------------------------------------
  40.  */
  41.  
  42. #define DCT_recon blockPtr->dct_recon
  43. #define DCT_dc_y_past blockPtr->dct_dc_y_past
  44. #define DCT_dc_cr_past blockPtr->dct_dc_cr_past
  45. #define DCT_dc_cb_past blockPtr->dct_dc_cb_past
  46.  
  47. void ParseReconBlock(int n)
  48. {
  49.     Block *blockPtr = &curVidStream->block;
  50.     int diff, level, run, pos, coeff, qscale;
  51.     short int *reconptr=DCT_recon[0];
  52.     unsigned short *iqmatrixptr;
  53.  
  54.     if (bufLength < 100) correct_underflow();
  55.  
  56.     clear64words(reconptr=DCT_recon[0]);
  57.  
  58.     if (curVidStream->mblock.mb_intra) {
  59.  
  60.       if (n < 4) {    /* Get the luminance bits. */
  61.  
  62.       /* Parse and decode size of first coefficient and itself. */
  63.       DecodeDCTDCSizeLum(diff);
  64.     coeff = diff << 3;
  65.  
  66.     if (n == 0) {
  67.       if (curVidStream->mblock.mb_address - curVidStream->mblock.past_intra_addr > 1) 
  68.         coeff += 1024;
  69.       else coeff += DCT_dc_y_past;
  70.     } else
  71.       coeff += DCT_dc_y_past;
  72.     DCT_dc_y_past = coeff;
  73.  
  74.       } else {
  75.     
  76.       /* Parse and decode size of first coefficient and itself. */
  77.       DecodeDCTDCSizeChrom(diff);
  78.     coeff = diff << 3;
  79.  
  80.     if (n == 4) {
  81.       if (curVidStream->mblock.mb_address - curVidStream->mblock.past_intra_addr > 1) 
  82.         coeff += 1024;
  83.       else
  84.         coeff += DCT_dc_cr_past;
  85.       DCT_dc_cr_past = coeff;
  86.  
  87.     } else {
  88.       if (curVidStream->mblock.mb_address - curVidStream->mblock.past_intra_addr > 1) 
  89.         coeff += 1024;
  90.       else
  91.         coeff += DCT_dc_cb_past;
  92.       DCT_dc_cb_past = coeff;
  93.     }
  94.       }
  95.  
  96.       *reconptr = coeff;
  97.     
  98.       if (curVidStream->picture.code_type != 4) {
  99.     recon_intra(curVidStream->intra_quant_matrix_ptr[curVidStream->slice.quant_scale], reconptr);
  100.       }
  101.       else
  102.     j_rev_dct(reconptr);
  103.  
  104.     } else { /* not an intra-frame */
  105.       
  106.       qscale = curVidStream->slice.quant_scale;
  107.  
  108.       DecodeDCTCoeffFirst(run, level);
  109.       pos = zigzag_direct[run];
  110.  
  111.       if (curVidStream->non_intra_default)
  112.       {
  113.     qscale <<= 4;
  114.     reconptr[pos] = ((short)level * (short)qscale) >> 3;
  115.  
  116.     if (curVidStream->picture.code_type != 4) {
  117.       recon_nonintra(qscale, run, reconptr);
  118.     }
  119.     else
  120.       j_rev_dct(reconptr);
  121.  
  122.       } else {
  123.     iqmatrixptr = curVidStream->non_intra_quant_matrix_ptr[qscale];
  124.  
  125.     reconptr[pos] = ((short)level * iqmatrixptr[run]) >> 3;
  126.  
  127.     if (curVidStream->picture.code_type != 4) {
  128.       recon_non2intra(run, iqmatrixptr, reconptr);
  129.     }
  130.     else
  131.       j_rev_dct(reconptr); // eventually, the flush(2) must be applied here, too ? hmmm
  132.  
  133.       }
  134.     }
  135. }
  136.     
  137. #undef DCT_recon 
  138. #undef DCT_dc_y_past 
  139. #undef DCT_dc_cr_past 
  140. #undef DCT_dc_cb_past 
  141.  
  142.  
  143.  
  144. /*
  145.  *--------------------------------------------------------------
  146.  *
  147.  * ParseAwayBlock --
  148.  *
  149.  *    Parses off block values, throwing them away.
  150.  *      Used with grayscale dithering.
  151.  *
  152.  * Results:
  153.  *    None.
  154.  *
  155.  * Side effects:
  156.  *      None.
  157.  *
  158.  * To do:
  159.  *      Move to sutils.s !!
  160.  *
  161.  *--------------------------------------------------------------
  162.  */
  163.  
  164. void ParseAwayBlock(int n)
  165. {
  166.   unsigned int diff, run;
  167.   int level;
  168.  
  169.   if (bufLength < 100) correct_underflow();
  170.  
  171.   if (curVidStream->mblock.mb_intra) {
  172.  
  173.     /* If the block is a luminance block... */
  174.  
  175.     if (n < 4) {
  176.       /* Parse and decode size of first coefficient and itself. */
  177.       DecodeDCTDCSizeLum(diff);
  178.     }
  179.     /* Otherwise, block is chrominance block... */
  180.     else {
  181.       /* Parse and decode size of first coefficient and itself. */
  182.       DecodeDCTDCSizeChrom(diff);
  183.     }
  184.   }
  185.   /* Otherwise, block is not intracoded... */
  186.   else {
  187.  
  188.     /* Decode and set first coefficient. */
  189.     DecodeDCTCoeffFirst(run, level);
  190.   }
  191.  
  192.   /* If picture is not D type (i.e. I, P, or B)... */
  193.  
  194.   if (curVidStream->picture.code_type != 4) {
  195.  
  196.     /* While end of macroblock has not been reached... */
  197.  
  198.     do {
  199.       DecodeDCTCoeffNext(run, level);    /* Get the dct_coeff_next */
  200.     } while (run != END_OF_BLOCK);
  201.  
  202.     /* End_of_block */
  203.     flush_bits(2);
  204.  
  205.   }
  206. }
  207.